home *** CD-ROM | disk | FTP | other *** search
/ Mac Mania 5 / MacMania 5.toast / / Tools&Utilities / Plotfoil 3.2 / plotfoil.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-09-19  |  8.5 KB  |  342 lines  |  [TEXT/MMCC]

  1. /*
  2.  * Copyright 1992,1994,1995 Shamim P. Mohamed
  3.  *
  4.  * This program is free software; you can redistribute it and/or modify
  5.  * it under the terms of the GNU General Public License as published by
  6.  * the Free Software Foundation; either version 2 of the License, or
  7.  * (at your option) any later version.
  8.  *
  9.  * This program is distributed in the hope that it will be useful,
  10.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.  * GNU General Public License for more details.
  13.  *
  14.  * You should have received a copy of the GNU General Public License
  15.  * along with this program; if not, write to the Free Software
  16.  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17.  *
  18.  * Author:
  19.  * shamim@math.isu.edu
  20.  * Shamim Mohamed
  21.  * Dept. of Mathematics
  22.  * Idaho State University
  23.  *
  24.  * Code reorganisation help from:
  25.  * David Lindner
  26.  * lindner@zk3.dec.com
  27.  * DEC
  28.  * ---------------------------------------------------------------------------
  29.  *
  30.  * Plots airfoils (or indeed any section)
  31.  * ---------------------------------------------------------------------------
  32.  * There are two formats for input data. Here are examples of each:
  33.  *
  34.  * Input format:
  35.  *    Title
  36.  *    1.0    0
  37.  *    0.9    0.011
  38.  *    0.85    0.02
  39.  *    ...
  40.  *    1.0    0
  41.  * This should start at the trailing edge (x = 1.0), follow a surface to the
  42.  * LE (x = 0), and continue back to the TE (assuming the LE is smooth).
  43.  *
  44.  * Lines beginning with # or % are comments, and are ignored.
  45.  *
  46.  * ---------------------------------------------------------------------------
  47.  * Options:
  48.  *    look for the string "usage_str".
  49.  */
  50.  
  51. #include "plotfoil.h"
  52. #include "externs.h"
  53.  
  54. /* global variables - these are modified by ui.c */
  55.  
  56. int sflag, iflag, tflag, nsheets_h, nsheets_v, nspars=0, aflag=0;
  57. float s_limit = 0.025;
  58. float c_height, c_depth;
  59. float angle = 0.0;
  60.  
  61. value_t
  62.    chord = {100.0, 2.834, 283.4, "mm"},
  63.    sheeting = {0.0, 1.0, 0.0, ""},
  64.    templ_h = {0.0, 1.0, 0.0, ""},
  65.    templ_le = {0.0, 1.0, 0.0, ""},
  66.    templ_te = {0.0, 1.0, 0.0, ""},
  67.    xfudge = {0.0, 1.0, 0.0, ""},
  68.    yfudge = {0.0, 1.0, 0.0, ""};
  69.  
  70. spar_t spars[MAX_SPARS];         /* spars for airfoil */
  71. FILE *fout = stdout;             /* output fd */
  72. int multipage = 0;               /* Is it a multipage plot? */
  73.  
  74. /*
  75.  * function declarations
  76.  */
  77.  
  78. static void plot_points(airfoil_data_t *);
  79. static void get_value(char *, value_t *);
  80. static void do_scaling(value_t *, value_t *);
  81. static void process(FILE *, char *);
  82.  
  83. void plot(airfoil_data_t *);
  84.  
  85. static char usage_str[] = "\n\
  86. Usage: %s [-hqs] [-c <n>[cim]] [-l <n>] [-i <n>] [-x <n>] [-y <n>]\n\
  87. [-sp <offset> <thickness>] [-tt <n>] [-th <n>] [-tl <n>] [-o outfile] [files]\n\
  88.    -h : Print this message\n\
  89.    -q : Skip the copyright message at startup\n\
  90.    -s : Use straight-line segments for x > s_limit\n\
  91. These take arguments:\n\
  92.    -x : Move the plot on the page to the right this much\n\
  93.    -y : Move the plot up by this much\n\
  94.    -c : Set chord size. A trailing unit can be specified:\n\
  95.         c = cm, i = inches, m = mm (default)\n\
  96.    -l : Set s_limit to n (default is 0.025)\n\
  97.    -i : Draw sheeting allowance of n units (units same as chord)\n\
  98.    -sp: Draw a spar at offset (in %% chord) of specified thickness\n\
  99.    -a : Turn the section by this angle (deg.; positive is counter-clockwise)\n\
  100.    -tl,\n\
  101.    -tt,\n\
  102.    -th: Draw template outlines of specified size (le, te, height)\n\
  103.    -o : Write output to file\n\
  104. (Under MS-DOS, / can be used instead of - for options.)\n\
  105. \n\
  106. A good place to start is:\n\
  107.  %s -c 200m -o file.ps filename\n\n\
  108. Typing just \"plotfoil\" will enter the interactive mode. Not in MacPlotfoil!\n\n";
  109.  
  110. int main(int argc, char *argv[])
  111. {
  112.    int i, qflag=0;
  113.    char *p, *fname;
  114.    FILE *fp, *get_file();
  115.    int argp = 1;
  116.  
  117.    /* Special case: with no arguments, go into prompt mode. */
  118.    if(argc == 1) {
  119.     /*  prompt_mode(); */
  120.       exit(0);
  121.    }
  122.    argc=ccommand(&argv);
  123.    while(argc > argp) {
  124.       p = argv[argp];
  125.       if(optionchar(*p) && (*(p+1) != 0)) {
  126.      switch (*(p+1)) {
  127.      case 'l':
  128.         sscanf(argv[++argp], "%f", &s_limit);
  129.         s_limit /= 100.0;
  130.         break;
  131.      case 's':
  132.         if(*(p+2) == 'p') {
  133.            sscanf(argv[++argp], "%f", &spars[nspars].offset);
  134.            get_value(argv[++argp], &spars[nspars].thick);
  135.            spars[nspars].offset /= 100.0;
  136.            nspars++;
  137.         }
  138.         else
  139.            sflag++;
  140.         break;
  141.      case 'q': qflag++; break;
  142.      case 'i':
  143.         iflag++;
  144.         get_value(argv[++argp], &sheeting);
  145.         break;
  146.      case 'c':
  147.         get_value(argv[++argp], &chord);
  148.         break;
  149.      case 'a':
  150.         aflag++;
  151.         sscanf(argv[++argp], "%f", &angle);
  152.         break;
  153.      case 't':
  154.         tflag++;
  155.         switch (*(p+2)) {
  156.         case 'h':
  157.            get_value(argv[++argp], &templ_h);
  158.            break;
  159.         case 't':
  160.            get_value(argv[++argp], &templ_te);
  161.            break;
  162.         case 'l':
  163.            get_value(argv[++argp], &templ_le);
  164.            break;
  165.         default:
  166.            fprintf(stderr, usage_str, argv[0], argv[0]);
  167.            break;
  168.         }
  169.         break;
  170.      case 'o':
  171.         fname = argv[++argp];
  172.         if((fout = fopen(fname, "w")) == NULL) {
  173.            fprintf(stderr, "Could not open \"%s\" for writing!\n", fname);
  174.            fout = stdout;
  175.         }
  176.         break;
  177. /*     case 'p':
  178.         prompt_mode();
  179.         exit(0);*/
  180.      case 'x':
  181.         get_value(argv[++argp], &xfudge);
  182.         break;
  183.      case 'y':
  184.         get_value(argv[++argp], &xfudge);
  185.         break;
  186.      case '-':
  187.         goto done_opts;
  188.      default:
  189.         fprintf(stderr, "Unknown option: %c%c\n", p[0], p[1]);
  190.      case 'h':
  191.      case '?':
  192.         fprintf(stderr, usage_str, argv[0], argv[0]);
  193.         exit(1);
  194.      }
  195.       }
  196.       else
  197.      break;
  198.       argp++;
  199.    }
  200.  
  201.  done_opts:
  202.    
  203.    if(!qflag)
  204.       fputs(copyright, stderr);
  205.  
  206.    if(*chord.units == '\0') {
  207.       chord.units = "mm";
  208.       chord.scale = 2.834;
  209.    }
  210.    do_scaling(&chord, 0);
  211.    do_scaling(&sheeting, &chord);
  212.    do_scaling(&templ_h, &chord);
  213.    do_scaling(&templ_te, &chord);
  214.    do_scaling(&templ_le, &chord);
  215.    do_scaling(&xfudge, &chord);
  216.    do_scaling(&yfudge, &chord);
  217.    for(i = 0; i < nspars; i++)
  218.       do_scaling(&spars[i].thick, &chord);
  219.    
  220.    if(argp >= argc)
  221.       process(stdin, "<stdin>");
  222.    else
  223.       for (; argp < argc; argp++) {
  224.          if((fp = fopen(argv[argp], "r")) == NULL) {
  225.             fprintf(stderr, "%s: can't open \"%s\"\n", argv[0], argv[argp]);
  226.             continue;
  227.          }
  228.          process(fp, argv[argp]);
  229.          fclose(fp);
  230.       }
  231.  
  232.    exit(0);
  233.  
  234.    /* well... */
  235.    return 0;
  236. }
  237.  
  238. static void process(FILE *fp, char *fname)
  239. {
  240.    airfoil_data_t data;
  241.    if(!(read_foil(fp, fname, &data)))
  242.       return;
  243.    plot(&data);
  244. }
  245.   
  246. void get_value(char *s, value_t *val)
  247. {
  248.    char c;
  249.    
  250.    if(sscanf(s, "%f%c", &val->raw_value, &c) == 1) {
  251.       val->scale = 1.0;
  252.       val->units = "";
  253.    }
  254.    else
  255.       switch((int)c) {
  256.       case 'i': val->scale = 72.0; val->units = "\""; break;
  257.       case 'c': val->scale = 28.34; val->units = "cm"; break;
  258.       case 'm':
  259.       default:
  260.      val->units = "mm";
  261.      val->scale = 2.834; break;
  262.       }
  263.    val->pts = val->raw_value * val->scale;
  264. }
  265.  
  266. void do_scaling(val, master)
  267. value_t *val, *master;
  268. {
  269.    if(val->units[0] == '\0' && master) {
  270.       val->units = master->units;
  271.       val->scale = master->scale;
  272.    }
  273.    val->pts = val->raw_value * val->scale;
  274. }
  275.  
  276. void plot(airfoil_data_t *info)
  277. {
  278.    int vsize;
  279.    
  280.    c_height = info->maxy * chord.pts;
  281.    c_depth = info->miny * chord.pts;
  282.    if(tflag)
  283.       vsize = 2*templ_h.pts;
  284.    else
  285.       vsize = (c_height - c_depth)*1.2;
  286.    nsheets_v = vsize/PAGEHEIGHT + 1;
  287.    nsheets_h = (int)(chord.pts+templ_te.pts+templ_le.pts)/PAGEWIDTH + 1;
  288.    multipage = (nsheets_h > 1) || (nsheets_v > 1);
  289.  
  290.    init_output(info->title);
  291.    plot_points(info);
  292.    end_output(info->points, info->npoints);
  293. }
  294.  
  295. /* Misc. math. */
  296. double sqr(double x)
  297. {
  298.    return x*x;
  299. }
  300.  
  301. #define px(i) (info->points[(i)].x)
  302. #define py(i) (info->points[(i)].y)
  303.  
  304. static void plot_points(airfoil_data_t *info)
  305. {
  306.    int i, j;
  307.    double d = 3.0, e = 0.2;
  308.  
  309.    if(tflag) {
  310.       draw_template(templ_h.pts, templ_le.pts, templ_te.pts);
  311.    }
  312.  
  313.    i = 0;
  314.  
  315.    if(sflag) {
  316.       /* In the region s_limit to 100%, use straight lines to plot */
  317.       i = 1;
  318.       init_lines(px(0), py(0));
  319.       while(px(i) > s_limit && px(i) < 1.0) {
  320.          put_line(px(i), py(i));
  321.          i++;
  322.       }
  323.       i--;
  324.       
  325.       for(j = i+1; px(j) <= s_limit && px(j) <= 1.0; j++)
  326.      ;
  327.       
  328.       interpolate(info->points+i, j-i-1, d, e, init_lines, put_curve);
  329.       
  330.       i = j;
  331.       /* Finish off rest i.e. 2.5% to 100% with straight lines */
  332.       for(;;) {
  333.      put_line(px(i), py(i));
  334.      if(px(i++) >= 1.0) break;
  335.       }
  336.    }
  337.    else
  338.       interpolate(info->points, info->npoints, d, e, init_lines, put_curve);
  339.  
  340. }
  341.  
  342.